#include "GL/glut.h"
#include "time.h"
#include <cmath>
#include <map>
#include <iostream>
#include "planet.h"

using namespace std;

long frameclock = 0;
double planet::AUshrink = 500.0;
double planet::earthYearTime = 0.1;	

planet::planetArr plnarr;

planet::planet(string pn, 
		double r, double m, double rtp, double rvr, double rvp, double rtrv, double rvre,
		double cr, double cg, double cb)
{
	this->name = pn;
	this->radius = r;
	this->mass = m;
	this->rotationPeriod = rtp;
	this->rotationAngle = 0.0;
	this->revolutionRadius = rvr;
	this->revolutionPeriod = rvp;	
	this->revolutionAngle = 0.0;
	this->rtrvAngle = rtrv;
	this->rvreAngle = rvre;

	this->colorr = cr;
	this->colorg = cg;
	this->colorb = cb;

	this->clstnum = 0;
	this->rvCircle = 0;
}

void planet::draw(long step)
{
	if(step>0)
	{
		double stepSecond = double(step)/CLOCKS_PER_SEC; //CLOCKS_PER_SEC defined in time.h
		double stepAngle = stepSecond*planet::PAI/(planet::earthYearTime*180*this->revolutionPeriod);
		this->revolutionAngle = stepAngle;
	}
	/*
	if(0 == this->name.compare("earth"))
	{	
		cout<<step<<" "<<this->revolutionAngle<<endl;
	}
	//*/
	double rvRadiusDraw = this->revolutionRadius * planet::AU / planet::AUshrink;

	if(0 == this->clstnum)
	{
		this->clstnum = glGenLists(1);
		glNewList(this->clstnum, GL_COMPILE);
		{
			glColor3f(this->colorr, this->colorg, this->colorb);
			glutSolidSphere(this->radius, 20, 20);
		}
		glEndList();	
	}
	if(0 == this->rvCircle)
	{
		this->rvCircle = glGenLists(1);
		glNewList(this->rvCircle, GL_COMPILE);
		{
			glColor3f(this->colorr, this->colorg, this->colorb);
			glBegin(GL_LINE_LOOP);
			for(double i=0.0; i<2*planet::PAI; i += 0.1)
			{
				glVertex3f(cos((i))*rvRadiusDraw, sin((i))*rvRadiusDraw, 0.0);
			}
			glEnd();
		}
		glEndList();
	}

	if(0 == this->name.compare("sun"))
	{
		glCallList(this->clstnum);
	}
	else
	{
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();

		//glLoadIdentity();
		glRotatef((this->rvreAngle), 0.0, 1.0, 0.0);
		glCallList(this->rvCircle);
		//cout<<this->name<<":"<<this->rvreAngle<<endl;

		glRotatef(this->revolutionAngle*180.0/planet::PAI, 0.0, 0.0, 1.0);
		glTranslatef(rvRadiusDraw, 0.0, 0.0);

		glCallList(this->clstnum);

		glMatrixMode(GL_MODELVIEW);
		glPopMatrix();
	}
}

void solaryInitial()
{
	//半径，质量，自转周期，公转半径，公转周期, 黄赤交角，公转轨道面角
	planet *sun 	= new planet(("sun"), 
			10.9125,	333400,	25.38,	0.0, 	0.0, 	0.0,	0.0);
	plnarr.push_back(sun);

	planet *mercury = new planet(("mercury"), 
			0.382565,	0.056,	58.65,	0.3871,	0.2409,	0.0,	7.005,
			0.0, 	1.0, 	0.0);
	plnarr.push_back(mercury);

	planet *venus 	= new planet(("venus"), 
			0.949,		0.857,	243.02,	0.7233,	0.6125,	177.4,	3.395,
			1.0, 	1.0, 	0.0);
	plnarr.push_back(venus);

	planet *earth 	= new planet(("earth"), 
			1.0,		1.00,	1.0,	1.0,	1.0,	23.44,	0.0,
			0.0, 	0.0, 	1.0);
	plnarr.push_back(earth);

	planet *mars 	= new planet(("mars"), 
			0.5326121,	0.151,	1.0260,	1.5237,	1.8809,	25.19,	1.85);
	plnarr.push_back(mars);

	planet *jupiter = new planet(("jupiter"), 
			11.209,		1321,	0.4135,	5.2026,	11.862,	3.08,	1.303,
			1.0, 	0.5, 	0.0);
	plnarr.push_back(jupiter);

	planet *saturn 	= new planet(("saturn"), 
			9.449357,	755,	0.444,	9.5549,	29.458,	26.7,	2.489,
			0.5, 	0.5, 	0.0);
	plnarr.push_back(saturn);

	planet *uranus 	= new planet(("uranus"), 
			4.007369,	63,		0.7183,	19.22,	84.022,	97.9,	0.773,
			0.0, 	0.0, 	0.8);
	plnarr.push_back(uranus);

	planet *neptune = new planet(("neptune"), 
			3.88272,	58,		0.6713,	30.11,	164.774,27.8,	1.770, 
			0.0, 	0.0, 	0.5);
	plnarr.push_back(neptune);
}

void solaryDraw()
{
	if(0 == plnarr.size())
	{
		solaryInitial();
	}

	glDisable(GL_TEXTURE_2D);

	glColor3f(1.0, 0.0, 0.0);
	glBegin(GL_LINES);
	glVertex3f(0.0,0.0,0.0);
	glVertex3f(100.0,0.0,0.0);   
	glEnd();

	glColor3f(0.0, 1.0, 0.0);
	glBegin(GL_LINES);
	glVertex3f(0.0,0.0,0.0);
	glVertex3f(0.0,100.0,0.0);
	glEnd();

	glColor3f(0.0, 0.0, 1.0);
	glBegin(GL_LINES);
	glVertex3f(0.0, 0.0, 0.0);
	glVertex3f(0.0, 0.0, 100.0);
	glEnd();

	long nowclock = clock();
	long step = nowclock - frameclock;
	//cout<<step<<endl;
	for(planet::planetArr::iterator itr = plnarr.begin(); itr != plnarr.end(); ++itr)
	{
		(*itr)->draw(step);
	}
}

//*
typedef vector<int> card;
typedef vector<card* > cardsarr;
typedef map<int, cardsarr *  > dianCards;
dianCards thecm;

int dcompute(card* ps, int i, int j, int k, int& add1, int& add2)
{
	add1 = -1;
	add2 = -1;
	int dian = 0;
	for(int kk=0; kk<5; ++kk)
	{
		if(kk != i && kk != j && kk != k)
		{
			add1 = kk;
			break;
		}
	}
	for(int kk=0; kk<5; ++kk)
	{
		if(kk != i && kk != j && kk != k && kk != add1)
		{
			add2 = kk;
			break;
		}
	}
	if(add1 >=0 && add2 >=0)
	{
		dian = (*ps)[add1]+(*ps)[add2];
		dian = (10<dian) ? dian-10 : dian;
		return dian;
	}
	return -1;
}

bool canbegood(card* ps)
{
	int add1, add2;
	for(int i=0; i<5; ++i)
	{
		for(int j=0; j<5; ++j)
		{
			if(i==j)
			{
				continue;
			}
			for(int k=0; k<5; ++k)
			{
				if(i==k || j==k)
				{
					continue;
				}
				if(20 == (*ps)[i]+(*ps)[j]+(*ps)[k])
				{
					int dian = dcompute(ps, i, j, k, add1, add2);
					if(0<dian)
					{
						if(10==dian)
						{
							//cout<<i<<"\t"<<j<<"\t"<<k<<"\t"<<add1<<"\t"<<add2<<endl;
							//cout<<"--"<<(*ps)[i]<<"\t"<<(*ps)[j]<<"\t"<<(*ps)[k]<<"\t"<<(*ps)[add1]<<"\t"<<(*ps)[add2]<<"\t"<<dian<<endl;
							thecm[11]->push_back(ps);		
						}
						else
						{
							if(thecm.end() != thecm.find(dian))
							{
								thecm[dian]->push_back(ps);		
							}
						}
					}
					return true;
				}
				if(10 == (*ps)[i]+(*ps)[j]+(*ps)[k])
				{
					int dian = dcompute(ps, i, j, k, add1, add2);
					if(0<dian)
					{
						if(thecm.end() != thecm.find(dian))
						{
							thecm[dian]->push_back(ps);		
						}
					}
					return true;
				}
			}
		}
	}
	return false;
}

int pcomputemain()
{
	thecm.clear();
	thecm[1]= new cardsarr();
	thecm[2]= new cardsarr();
	thecm[3]= new cardsarr();
	thecm[4]= new cardsarr();
	thecm[5]= new cardsarr();
	thecm[6]= new cardsarr();
	thecm[7]= new cardsarr();
	thecm[8]= new cardsarr();
	thecm[9]= new cardsarr();
	thecm[10]= new cardsarr();
	thecm[11]= new cardsarr();

	cout<<"computing begin"<<endl;
	int ccount = 0;
	for(int i1=1; i1<10; ++i1)
	{
		for(int i2=1; i2<10; ++i2)
		{
			for(int i3=1; i3<10; ++i3)
			{
				for(int i4=1; i4<10; ++i4)
				{
					for(int i5=1; i5<10; ++i5)
					{
						if(i1 == i2 && i2 == i3 && i3 == i4 && i4 == i5)
						{
							continue;
						}
						card* ps = new card;
						ps->push_back(i1);
						ps->push_back(i2);
						ps->push_back(i3);
						ps->push_back(i4);
						ps->push_back(i5);
						canbegood(ps);
						++ccount;	
					}	
				}
			}
		}
	}
	cout<<"computing end"<<endl;

	double ratecount =0.0;
	for(dianCards::iterator tmpitr = thecm.begin();
		tmpitr != thecm.end();
		++tmpitr)
	{
		double rate = double(tmpitr->second->size())/double(ccount);
		ratecount += rate;
		rate *= 100.0;
		cout<<tmpitr->first<<"\t"<<(tmpitr->second)->size()<<"\t"<<rate<<"%"<<endl;
	}
	
	cout<<ratecount<<endl;
	for(dianCards::iterator tmpitr = thecm.begin();
		tmpitr != thecm.end();
		++tmpitr)
	{
		cardsarr* tmpcsptr  = tmpitr->second;
		delete tmpcsptr;
	}

	
	return 0;
}//*/
